home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / progjour / 1989 / 02 / animate.asm next >
Assembly Source File  |  1988-12-12  |  15KB  |  500 lines

  1. ;
  2. ; *** Listing 1 ***
  3. ;
  4. ; Program to demonstrate bit-plane animation. Performs
  5. ; flicker-free animation with image transparency and
  6. ; image precedence across four distinct planes, with
  7. ; 13 32x32 images kept in motion at once.
  8. ;
  9. ;
  10. ; Set to higher values to slow down on faster computers.
  11. ; 0 is fine for a PC. 500 is a reasonable setting for an AT.
  12. ; Slowing animation further allows a good look at
  13. ; transparency and the lack of flicker and color effects
  14. ; when images cross.
  15. ;
  16. SLOWDOWN    equ    0
  17. ;
  18. ; Plane selects for the four colors we're using.
  19. ;
  20. RED    equ    01h
  21. GREEN    equ    02h
  22. BLUE    equ    04h
  23. WHITE    equ    08h
  24. ;
  25. VGA_SEGMENT    equ    0a000h    ;mode 10h display memory
  26.                 ; segment
  27. SC_INDEX    equ    3c4h    ;Sequence Controller Index
  28.                 ; register
  29. MAP_MASK    equ    2    ;Map Mask register index in
  30.                 ; Sequence Controller
  31. SCREEN_WIDTH    equ    80    ;# of bytes across screen
  32. SCREEN_HEIGHT    equ    350    ;# of scan lines on screen
  33. WORD_OUTS_OK    equ    1    ;set to 0 to assemble for
  34.                 ; computers that can't
  35.                 ; handle word outs to
  36.                 ; indexed VGA regs
  37. ;
  38. stack    segment para stack 'STACK'
  39.     db    512 dup (?)
  40. stack    ends
  41. ;
  42. ; Complete info about one object that we're animating.
  43. ;
  44. ObjectStructure    struc
  45. Delay        dw    ?    ;used to delay for n passes
  46.                 ; throught the loop to
  47.                 ; control animation speed
  48. BaseDelay    dw    ?    ;reset value for Delay
  49. Image        dw    ?    ;pointer to drawing info
  50.                 ; for object
  51. XCoord        dw    ?    ;object X location in pixels
  52. XInc        dw    ?    ;# of pixels to increment
  53.                 ; location by in the X
  54.                 ; direction on each move
  55. XLeftLimit    dw    ?    ;left limit of X motion
  56. XRightLimit    dw    ?    ;right limit of X motion
  57. YCoord        dw    ?    ;object Y location in pixels
  58. YInc        dw    ?    ;# of pixels to increment
  59.                 ; location by in the Y
  60.                 ; direction on each move
  61. YTopLimit    dw    ?    ;top limit of Y motion
  62. YBottomLimit    dw    ?    ;bottom limit of Y motion
  63. PlaneSelect    db    ?    ;mask to select plane to
  64.                 ; which object is drawn
  65.         db    ?    ;to make an even # of words
  66.                 ; long, for better 286
  67.                 ; performance (keeps the
  68.                 ; following structure
  69.                 ; word-aligned)
  70. ObjectStructure    ends
  71. ;
  72. Data    segment    word 'DATA'
  73. ;
  74. ; Palette settings to give plane 0 precedence, followed by
  75. ; planes 1, 2, and 3. Plane 3 has the lowest precedence (is
  76. ; obscured by any other plane), while plane 0 has the
  77. ; highest precedence (displays in front of any other plane).
  78. ;
  79. Colors    db    000h ;background color=black
  80.     db    03ch ;plane 0 only=red
  81.     db    03ah ;plane 1 only=green
  82.     db    03ch ;planes 0&1=red (plane 0 priority)
  83.     db    039h ;plane 2 only=blue
  84.     db    03ch ;planes 0&2=red (plane 0 priority)
  85.     db    03ah ;planes 1&2=green (plane 1 priority)
  86.     db    03ch ;planes 0&1&2=red (plane 0 priority)
  87.     db    03fh ;plane 3 only=white
  88.     db    03ch ;planes 0&3=red (plane 0 priority)
  89.     db    03ah ;planes 1&3=green (plane 1 priority)
  90.     db    03ch ;planes 0&1&3=red (plane 0 priority)
  91.     db    039h ;planes 2&3=blue (plane 2 priority)
  92.     db    03ch ;planes 0&2&3=red (plane 0 priority)
  93.     db    03ah ;planes 1&2&3=green (plane 1 priority)
  94.     db    03ch ;planes 0&1&2&3=red (plane 0 priority)
  95.     db    000h ;border color=black
  96. ;
  97. ; Image of a hollow square.
  98. ; There's an 8-pixel-wide blank border around all edges
  99. ; so that the image erases the old version of itself as
  100. ; it's moved and redrawn.
  101. ;
  102. Square    label    byte
  103.     dw    48,6    ;height in pixels, width in bytes
  104.     rept    8
  105.     db    0,0,0,0,0,0    ;top blank border
  106.     endm
  107.     .radix    2
  108.     db    0,11111111,11111111,11111111,11111111,0
  109.     db    0,11111111,11111111,11111111,11111111,0
  110.     db    0,11111111,11111111,11111111,11111111,0
  111.     db    0,11111111,11111111,11111111,11111111,0
  112.     db    0,11111111,11111111,11111111,11111111,0
  113.     db    0,11111111,11111111,11111111,11111111,0
  114.     db    0,11111111,11111111,11111111,11111111,0
  115.     db    0,11111111,11111111,11111111,11111111,0
  116.     db    0,11111111,00000000,00000000,11111111,0
  117.     db    0,11111111,00000000,00000000,11111111,0
  118.     db    0,11111111,00000000,00000000,11111111,0
  119.     db    0,11111111,00000000,00000000,11111111,0
  120.     db    0,11111111,00000000,00000000,11111111,0
  121.     db    0,11111111,00000000,00000000,11111111,0
  122.     db    0,11111111,00000000,00000000,11111111,0
  123.     db    0,11111111,00000000,00000000,11111111,0
  124.     db    0,11111111,00000000,00000000,11111111,0
  125.     db    0,11111111,00000000,00000000,11111111,0
  126.     db    0,11111111,00000000,00000000,11111111,0
  127.     db    0,11111111,00000000,00000000,11111111,0
  128.     db    0,11111111,00000000,00000000,11111111,0
  129.     db    0,11111111,00000000,00000000,11111111,0
  130.     db    0,11111111,00000000,00000000,11111111,0
  131.     db    0,11111111,00000000,00000000,11111111,0
  132.     db    0,11111111,11111111,11111111,11111111,0
  133.     db    0,11111111,11111111,11111111,11111111,0
  134.     db    0,11111111,11111111,11111111,11111111,0
  135.     db    0,11111111,11111111,11111111,11111111,0
  136.     db    0,11111111,11111111,11111111,11111111,0
  137.     db    0,11111111,11111111,11111111,11111111,0
  138.     db    0,11111111,11111111,11111111,11111111,0
  139.     db    0,11111111,11111111,11111111,11111111,0
  140.     .radix    10
  141.     rept    8
  142.     db    0,0,0,0,0,0    ;bottom blank border
  143.     endm
  144. ;
  145. ; Image of a hollow diamond with a smaller diamond in the
  146. ; middle.
  147. ; There's an 8-pixel-wide blank border around all edges
  148. ; so that the image erases the old version of itself as
  149. ; it's moved and redrawn.
  150. ;
  151. Diamond    label    byte
  152.     dw    48,6    ;height in pixels, width in bytes
  153.     rept    8
  154.     db    0,0,0,0,0,0    ;top blank border
  155.     endm
  156.     .radix    2
  157.     db    0,00000000,00000001,10000000,00000000,0
  158.     db    0,00000000,00000011,11000000,00000000,0
  159.     db    0,00000000,00000111,11100000,00000000,0
  160.     db    0,00000000,00001111,11110000,00000000,0
  161.     db    0,00000000,00011111,11111000,00000000,0
  162.     db    0,00000000,00111110,01111100,00000000,0
  163.     db    0,00000000,01111100,00111110,00000000,0
  164.     db    0,00000000,11111000,00011111,00000000,0
  165.     db    0,00000001,11110000,00001111,10000000,0
  166.     db    0,00000011,11100000,00000111,11000000,0
  167.     db    0,00000111,11000000,00000011,11100000,0
  168.     db    0,00001111,10000001,10000001,11110000,0
  169.     db    0,00011111,00000011,11000000,11111000,0
  170.     db    0,00111110,00000111,11100000,01111100,0
  171.     db    0,01111100,00001111,11110000,00111110,0
  172.     db    0,11111000,00011111,11111000,00011111,0
  173.     db    0,11111000,00011111,11111000,00011111,0
  174.     db    0,01111100,00001111,11110000,00111110,0
  175.     db    0,00111110,00000111,11100000,01111100,0
  176.     db    0,00011111,00000011,11000000,11111000,0
  177.     db    0,00001111,10000001,10000001,11110000,0
  178.     db    0,00000111,11000000,00000011,11100000,0
  179.     db    0,00000011,11100000,00000111,11000000,0
  180.     db    0,00000001,11110000,00001111,10000000,0
  181.     db    0,00000000,11111000,00011111,00000000,0
  182.     db    0,00000000,01111100,00111110,00000000,0
  183.     db    0,00000000,00111110,01111100,00000000,0
  184.     db    0,00000000,00011111,11111000,00000000,0
  185.     db    0,00000000,00001111,11110000,00000000,0
  186.     db    0,00000000,00000111,11100000,00000000,0
  187.     db    0,00000000,00000011,11000000,00000000,0
  188.     db    0,00000000,00000001,10000000,00000000,0
  189.     .radix    10
  190.     rept    8
  191.     db    0,0,0,0,0,0    ;bottom blank border
  192.     endm
  193. ;
  194. ; List of objects to animate.
  195. ;
  196.     even    ;word-align for better 286 performance
  197. ;
  198. ObjectList    label    ObjectStructure
  199.  ObjectStructure <1,21,Diamond,88,8,80,512,16,0,0,350,RED>
  200.  ObjectStructure <1,15,Square,296,8,112,480,144,0,0,350,RED>
  201.  ObjectStructure <1,23,Diamond,88,8,80,512,256,0,0,350,RED>
  202.  ObjectStructure <1,13,Square,120,0,0,640,144,4,0,280,BLUE>
  203.  ObjectStructure <1,11,Diamond,208,0,0,640,144,4,0,280,BLUE>
  204.  ObjectStructure <1,8,Square,296,0,0,640,144,4,0,288,BLUE>
  205.  ObjectStructure <1,9,Diamond,384,0,0,640,144,4,0,288,BLUE>
  206.  ObjectStructure <1,14,Square,472,0,0,640,144,4,0,280,BLUE>
  207.  ObjectStructure <1,8,Diamond,200,8,0,576,48,6,0,280,GREEN>
  208.  ObjectStructure <1,8,Square,248,8,0,576,96,6,0,280,GREEN>
  209.  ObjectStructure <1,8,Diamond,296,8,0,576,144,6,0,280,GREEN>
  210.  ObjectStructure <1,8,Square,344,8,0,576,192,6,0,280,GREEN>
  211.  ObjectStructure <1,8,Diamond,392,8,0,576,240,6,0,280,GREEN>
  212. ObjectListEnd    label    ObjectStructure
  213. ;
  214. Data    ends
  215. ;
  216. ; Macro to output a word value to a port.
  217. ;
  218. OUT_WORD    macro
  219. if WORD_OUTS_OK
  220.     out    dx,ax
  221. else
  222.     out    dx,al
  223.     inc    dx
  224.     xchg    ah,al
  225.     out    dx,al
  226.     dec    dx
  227.     xchg    ah,al
  228. endif
  229.     endm
  230. ;
  231. ; Macro to output a constant value to an indexed VGA
  232. ; register.
  233. ;
  234. CONSTANT_TO_INDEXED_REGISTER    macro ADDRESS, INDEX, VALUE
  235.     mov    dx,ADDRESS
  236.     mov    ax,(VALUE shl 8) + INDEX
  237.     OUT_WORD
  238.     endm
  239. ;
  240. Code    segment
  241.     assume    cs:Code, ds:Data
  242. Start    proc    near
  243.     cld
  244.     mov    ax,Data
  245.     mov    ds,ax
  246. ;
  247. ; Set 640x350 16-color mode.
  248. ;
  249.     mov    ax,0010h    ;AH=0 means select mode
  250.                 ;AL=10h means select
  251.                 ; mode 10h
  252.     int    10h        ;BIOS video interrupt
  253. ;
  254. ; Set the palette up to provide bit-plane precedence. If
  255. ; planes 0 & 1 overlap, the plane 0 color will be shown;
  256. ; if planes 1 & 2 overlap, the plane 1 color will be
  257. ; shown; and so on.
  258. ;
  259.     mov    ax,(10h shl 8) + 2    ;AH = 10h means
  260.                     ; set palette
  261.                     ; registers fn
  262.                     ;AL = 2 means set
  263.                     ; all palette
  264.                     ; registers
  265.     push    ds            ;ES:DX points to
  266.     pop    es            ; the palette
  267.     mov    dx,offset Colors    ; settings
  268.     int    10h            ;call the BIOS to
  269.                     ; set the palette
  270. ;
  271. ; Draw the static backdrop in plane 3. All the moving images
  272. ; will appear to be in front of this backdrop, since plane 3
  273. ; has the lowest precedence the way the palette is set up.
  274. ;
  275.     CONSTANT_TO_INDEXED_REGISTER SC_INDEX, MAP_MASK, 08h
  276.                 ;allow data to go to
  277.                 ; plane 3 only
  278. ;
  279. ; Point ES to display memory for the rest of the program.
  280. ;
  281.     mov    ax,VGA_SEGMENT
  282.     mov    es,ax
  283. ;
  284.     sub    di,di
  285.     mov    bp,SCREEN_HEIGHT/16    ;fill in the screen
  286.                     ; 16 lines at a time
  287. BackdropBlockLoop:
  288.     call    DrawGridCross        ;draw a cross piece
  289.     call    DrawGridVert        ;draw the rest of a
  290.                     ; 15-high block
  291.     dec    bp
  292.     jnz    BackdropBlockLoop
  293.     call    DrawGridCross        ;bottom line of grid
  294. ;
  295. ; Start animating!
  296. ;
  297. AnimationLoop:
  298.     mov    bx,offset ObjectList    ;point to the first
  299.                     ; object in the list
  300. ;
  301. ; For each object, see if it's time to move and draw that
  302. ; object.
  303. ;
  304. ObjectLoop:
  305. ;
  306. ; See if it's time to move this object.
  307. ;
  308.     dec    [bx+Delay]    ;count down delay
  309.     jnz    DoNextObject    ;still delaying-don't move
  310.     mov    ax,[bx+BaseDelay]
  311.     mov    [bx+Delay],ax    ;reset delay for next time
  312. ;
  313. ; Select the plane that this object will be drawn in.
  314. ;
  315.     mov    dx,SC_INDEX
  316.     mov    ah,[bx+PlaneSelect]
  317.     mov    al,MAP_MASK
  318.     OUT_WORD
  319. ;
  320. ; Advance the X coordinate, reversing direction if either
  321. ; of the X margins has been reached.
  322. ;
  323.     mov    cx,[bx+XCoord]        ;current X location
  324.     cmp    cx,[bx+XLeftLimit]    ;at left limit?
  325.     ja    CheckXRightLimit    ;no
  326.     neg    [bx+XInc]        ;yes-reverse
  327. CheckXRightLimit:
  328.     cmp    cx,[bx+XRightLimit]    ;at right limit?
  329.     jb    SetNewX            ;no
  330.     neg    [bx+XInc]        ;yes-reverse
  331. SetNewX:
  332.     add    cx,[bx+XInc]        ;move the X coord
  333.     mov    [bx+XCoord],cx        ; & save it
  334. ;
  335. ; Advance the Y coordinate, reversing direction if either
  336. ; of the Y margins has been reached.
  337. ;
  338.     mov    dx,[bx+YCoord]            ;current Y location
  339.     cmp    dx,[bx+YTopLimit]       ;at top limit?
  340.     ja    CheckYBottomLimit       ;no
  341.     neg    [bx+YInc]            ;yes-reverse
  342. CheckYBottomLimit:
  343.     cmp    dx,[bx+YBottomLimit]    ;at bottom limit?
  344.     jb    SetNewY                ;no
  345.     neg    [bx+YInc]            ;yes-reverse
  346. SetNewY:
  347.     add    dx,[bx+YInc]            ;move the Y coord
  348.     mov    [bx+YCoord],dx            ; & save it
  349. ;
  350. ; Draw at the new location. Because of the plane select
  351. ; above, only one plane will be affected.
  352. ;
  353.     mov    si,[bx+Image]        ;point to the
  354.                     ; object's image
  355.                     ; info
  356.     call    DrawObject
  357. ;
  358. ; Point to the next object in the list until we run out of
  359. ; objects.
  360. ;
  361. DoNextObject:
  362.     add    bx,size ObjectStructure
  363.     cmp    bx,offset ObjectListEnd
  364.     jb    ObjectLoop
  365. ;
  366. ; Delay as specified to slow things down.
  367. ;
  368. if SLOWDOWN
  369.     mov    cx,SLOWDOWN
  370. DelayLoop:
  371.     loop    DelayLoop
  372. endif
  373. ;
  374. ; If a key's been pressed, we're done, otherwise animate
  375. ; again.
  376. ;
  377. CheckKey:
  378.     mov    ah,1
  379.     int    16h        ;is a key waiting?
  380.     jz    AnimationLoop    ;no
  381.     sub    ah,ah
  382.     int    16h        ;yes-clear the key & done
  383. ;
  384. ; Back to text mode.
  385. ;
  386.     mov    ax,0003h    ;AL=03h means select
  387.                 ; mode 03h
  388.     int    10h
  389. ;
  390. ; Back to DOS.
  391. ;
  392.     mov    ah,4ch        ;DOS terminate function
  393.     int    21h        ;done
  394. ;
  395. Start    endp
  396. ;
  397. ; Draws a single grid cross-element at the display memory
  398. ; location pointed to by ES:DI. 1 horizontal line is drawn
  399. ; across the screen.
  400. ;
  401. ; Input: ES:DI points to the address at which to draw
  402. ;
  403. ; Output: ES:DI points to the address following the
  404. ;        line drawn
  405. ;
  406. ; Registers altered: AX, CX, DI
  407. ;
  408. DrawGridCross    proc    near
  409.     mov    ax,0ffffh    ;draw a solid line
  410.     mov    cx,SCREEN_WIDTH/2-1
  411.     rep    stosw        ;draw all but the rightmost
  412.                 ; edge
  413.     mov    ax,0080h
  414.     stosw            ;draw the right edge of the
  415.                 ; grid
  416.     ret
  417. DrawGridCross    endp
  418. ;
  419. ; Draws the non-cross part of the grid at the display memory
  420. ; location pointed to by ES:DI. 15 scan lines are filled.
  421. ;
  422. ; Input: ES:DI points to the address at which to draw
  423. ;
  424. ; Output: ES:DI points to the address following the
  425. ;        part of the grid drawn
  426. ;
  427. ; Registers altered: AX, CX, DX, DI
  428. ;
  429. DrawGridVert    proc    near
  430.     mov    ax,0080h    ;pattern for a vertical line
  431.     mov    dx,15        ;draw 15 scan lines (all of
  432.                 ; a grid block except the
  433.                 ; solid cross line)
  434. BackdropRowLoop:
  435.     mov    cx,SCREEN_WIDTH/2
  436.     rep    stosw        ;draw this scan line's bit
  437.                 ; of all the vertical lines
  438.                 ; on the screen
  439.     dec    dx
  440.     jnz    BackdropRowLoop
  441.     ret
  442. DrawGridVert    endp
  443. ;
  444. ; Draw the specified image at the specified location.
  445. ; Images are drawn on byte boundaries horizontally, pixel
  446. ; boundaries vertically.
  447. ; The Map Mask register must already have been set to enable
  448. ; access to the desired plane.
  449. ;
  450. ; Input:
  451. ;    CX - X coordinate of upper left corner
  452. ;    DX - Y coordinate of upper left corner
  453. ;    DS:SI - pointer to draw info for image
  454. ;    ES - display memory segment
  455. ;
  456. ; Output: none
  457. ;
  458. ; Registers altered: AX, CX, DX, SI, DI, BP
  459. ;
  460. DrawObject    proc    near
  461.     mov    ax,SCREEN_WIDTH
  462.     mul    dx    ;calculate the start offset in
  463.             ; display memory of the row the
  464.             ; image will be drawn at
  465.     shr    cx,1
  466.     shr    cx,1
  467.     shr    cx,1    ;divide the X coordinate in pixels
  468.             ; by 8 to get the X coordinate in
  469.             ; bytes
  470.     add    ax,cx    ;destination offset in display
  471.             ; memory for the image
  472.     mov    di,ax    ;point ES:DI to the address to
  473.             ; which the image will be copied
  474.             ; in display memory
  475.     lodsw
  476.     mov    dx,ax    ;# of lines in the image
  477.     lodsw        ;# of bytes across the image
  478.     mov    bp,SCREEN_WIDTH
  479.     sub    bp,ax    ;# of bytes to add to the display
  480.             ; memory offset after copying a line
  481.             ; of the image to display memory in
  482.             ; order to point to the address
  483.             ; where the next line of the image
  484.             ; will go in display memory
  485. DrawLoop:
  486.     mov    cx,ax    ;width of the image
  487.     rep    movsb    ;copy the next line of the image
  488.             ; into display memory
  489.     add    di,bp    ;point to the address at which the
  490.             ; next line will go in display
  491.             ; memory
  492.     dec    dx    ;count down the lines of the image
  493.     jnz    DrawLoop
  494.     ret
  495. DrawObject    endp
  496. ;
  497. Code    ends
  498.     end    Start
  499.  
  500.